#include "export.h"
#include "assert.h"
#include "exportDataCollection_t.h"



FILE* g_file = 0;
char* g_file_name = 0;
double g_execute_number = 1;
double g_function_number = 1;
double g_block_number = 1;
int g_block_size = 100;
extern methodCollection_t* g_gl;

void CALLBACK write_function(cmd_t* cmd, void* user)
{
	//MaData* m = (MaData*)user;
	void *savedESP;
	int i = findIndex(cmd->pFunc);
	const char* name = tabExportData[i].functionName;
	const char* format = tabExportData[i].format;
	size_t s = cmd->argsSize+sizeof(format)+sizeof(g_file);

	fprintf(g_file,"<function name = \"%s\" numberInTheBlock = \"%g\" numberInTheExecute = \"%g\">\n", name, g_function_number ,g_function_number+(g_block_number-1)*g_block_size);

	__asm
	{
		mov  savedESP, esp;
		sub  esp, s;
	}

	if(cmd->pArgs != 0)
		memcpy(((char*)savedESP)-s, cmd->pArgs, s);

	__asm
	{
		push format;
		push g_file;
		call fprintf;
		mov  esp, savedESP;
	}

	fprintf(g_file,"</function>\n");
	g_function_number++;
	if (g_function_number > g_block_size)
	{
		fprintf(g_file,"</block>\n");
		g_block_number++;
		fprintf(g_file,"<block number = \"%g\">\n",g_block_number);
		g_function_number = 1;
	}
}

void export_cb(cmdBuffer_t* cB)
{
	fprintf(g_file,"<execute number = \"%g\">\n",g_execute_number);
	fprintf(g_file,"<block number = \"%g\">\n",g_block_number);
	cmdBuffer_Enumerate(cB, write_function, 0);
	fprintf(g_file,"</block>\n</execute>\n");
	g_execute_number++;
	g_function_number = 1;
	g_block_number = 1;
}

void export_define_block_size(int size)
{
	g_block_size = size;
}

void export_change_file(char* name)
{
	export_close_file();
	export_init_file(name);
}

void export_init(char* name, methodCollection_t* gl)
{
	g_gl = gl;
	exportDataCollectionInit();
	export_init_file(name);
}

void export_init_file(char* name)
{
	g_file_name = name;
	if ((g_file = fopen(g_file_name,"w"))!=NULL)
	{
		fprintf(g_file,"<?xml version='1.0' encoding='ISO-8859-1'?>\n<debug>\n");
	}
	else
	{
		assert("Impossible d'ouvrir le fichier d'export");
	}
}

void export_close_file()
{
	if(g_file)
	{
		fprintf(g_file,"</debug>");
		fclose(g_file);
	}
}

void export_close()
{
	export_close_file();
}

int findIndex(void* pFunc)
{
	void* pointeurFunction;
	int i;
	for (i = 0 ; i < getTabExportDataSize() ; i++)
	{
		pointeurFunction = *(&(g_gl->hDll) + i + 1);
		if (pFunc == pointeurFunction)
		{
			return i;
		}
	}
	return -1;
}
